<script setup>
import { provide, ref , h, defineComponent, watch,reactive} from 'vue';
import HelloWorld from './components/HelloWorld.vue'
import Utils from './utils/index';
import log from './common';

const utils = new Utils();
utils.setParams(true);
provide('utils', utils);
provide("log", log)


const DynamicComponent  = {
  render: () => {
    return h('img', {
      class: ['logo', 'vue'],
      src: '/vite.svg',
      alt: 'Vue logo',
    });
  },
}
const dynamicComponent = ref(DynamicComponent)

Function.prototype.myCall = function (context) {
  // 判断调用对象
  if (typeof this !== "function") {
    console.error("type error");
  }
  // 获取参数
  let args = [...arguments].slice(1), result = null;
  // 判断 context 是否传入，如果未传入则设置为 window
  context = context || window;
  // 将调用函数设为对象的方法
  context.fn = this;
  // 调用函数
  result = context.fn(...args);
  // 将属性删除
  delete context.fn;
  return result;
};
// 测试一下
let person = {
    firstName: "张",
    lastName: "三",
    fullName: function() {
        return this.firstName + ' ' + this.lastName;
    }
};
window.firstName = "王";
window.lastName = "五";
let person2 = {
    firstName: "李",
    lastName: "四"
};
console.log(person.fullName.myCall(person2));

Function.prototype.myApply = function (context, args = []) {
  // 类似于 myCall 的检查
  if (typeof this !== 'function') {
    throw new TypeError('myApply must be called on a function');
  }

  // 设置上下文，默认为全局对象
  context = context || globalThis;

  // 使用 Symbol 创建临时属性存储原函数
  const key = Symbol();
  context[key] = this;

  // 根据规范，args 应该是一个数组或类数组对象，这里直接使用 spread 操作符传递
  const result = context[key](...args);

  // 清理
  delete context[key];

  return result;
};

Function.prototype.myBind = function (context, ...boundArgs) {
  // 类似于之前的检查
  if (typeof this !== 'function') {
    throw new TypeError('myBind must be called on a function');
  }

  // 返回一个新的函数，这个函数在调用时会使用预先设定的上下文和参数
  return function (...args) {
    // 使用 apply 来确保新函数能正确接收剩余的参数
    return this.myApply(context, boundArgs.concat(args));
  }.bind(this); // 确保新函数的`this`绑定为原函数
};
const message = ref({data:'hello world Parent'}) 

</script>

<template>
  <component :is="HelloWorld" v-model="message"></component>
  <h5>{{message}}</h5>
  <!-- <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div> -->
  <!-- <HelloWorld msg="Vite + Vue" /> -->
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
